home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 July / macformat-026.iso / mac / Shareware City / Science / µSim 1.0 folder / source / Assembler.c < prev    next >
Encoding:
Text File  |  1995-02-28  |  12.7 KB  |  475 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12. #include    <ctype.h>
  13. #include    <stdlib.h>
  14.  
  15. #include    "UtilsSys7.h"
  16. #include    "Assembler.h"
  17. #include    "Disasm.h"
  18. #include    "DoEditDialog.h"
  19. #include    "DoMenu.h"
  20. #include    "Dump.h"
  21. #include    "Globals.h"
  22. #include    "Main.h"
  23. #include    "Microprogram_Ed.h"
  24. #include    "MovableModal.h"
  25. #include    "SimUtils.h"
  26. #include    "Conversions.h"
  27.  
  28. #if defined(FabSystem7orlater)
  29.  
  30. #pragma segment Rare
  31.  
  32. enum {
  33. kOPCMAXLEN = 4,
  34. kGROW_SYMTAB = 50,
  35. kGROW_OBJTAB = 150,
  36. kBITS_12 = 0x0FFF,
  37. kBITS_11 = 0x07FF,
  38. kBITS_8 = 0x00FF
  39. };
  40.  
  41. struct symtable {
  42.     StringHandle    symb;
  43.     long    value;
  44.     };
  45.  
  46. typedef struct symtable symtable;
  47. typedef symtable *symtablePtr;
  48. typedef symtablePtr *symtableHandle;
  49.  
  50. #if defined(powerc) || defined (__powerc)
  51. #pragma options align=mac68k
  52. #endif
  53. struct objtable {
  54.     long    operand;
  55.     Byte    length;
  56.     Byte    class;
  57.     unsigned short    opcod;
  58.     Boolean    isSymbol;
  59.     Boolean    reserved;
  60.     };
  61. #if defined(powerc) || defined(__powerc)
  62. #pragma options align=reset
  63. #endif
  64.  
  65. typedef struct objtable objtable;
  66. typedef objtable *objtablePtr;
  67. typedef objtablePtr *objtableHandle;
  68.  
  69. static OSErr OnePassAsm(Handle fileBuffer);
  70. static long CountReturns(Handle fileBuffer, char *lastpos);
  71. static Boolean AsmPrefsPreProcessKey(EventRecord *thEv, DialogPtr theD);
  72. //static pascal Boolean AsmEditNumFilter(DialogPtr, EventRecord *, short *);
  73. static int compareMnem(const void *opc1, const void *opc2);
  74. static int cmpsymb(const void *opc1, const void *opc2);
  75.  
  76.  
  77. /* myAsmFile: reads theFile to be assembled into memory */
  78.  
  79. OSErr myAsmFile(FSSpec *theFile)
  80. {
  81. ParamBlockRec    myPB;
  82. EventRecord    dummyEv;
  83. register Handle    tempBuffer;
  84. unsigned long    fileSize;
  85. short    asmFileRefN;
  86. register OSErr    err;
  87.  
  88. SetCursor(*gWatchHandle);
  89. if ((err = FSpOpenDFCompat(theFile, fsRdPerm, &asmFileRefN)) == noErr) {
  90.     if ((err = GetEOF(asmFileRefN, (long *)&fileSize)) == noErr) {
  91.         if (tempBuffer = NewHandleGeneral(fileSize)) {
  92.             myPB.ioParam.ioCompletion = nil;
  93.             myPB.ioParam.ioRefNum = asmFileRefN;
  94.             HLock(tempBuffer);
  95.             myPB.ioParam.ioBuffer = *tempBuffer;
  96.             myPB.ioParam.ioReqCount = fileSize;
  97.             myPB.ioParam.ioPosMode = fsFromStart;
  98.             myPB.ioParam.ioPosOffset = 0L;
  99.             (void)PBReadAsync(&myPB);
  100.             while (myPB.ioParam.ioResult > 0) {
  101.                 SystemTask();
  102.                 (void)EventAvail(everyEvent, &dummyEv);
  103.                 }
  104.             HUnlock(tempBuffer);
  105.             if ((err = myPB.ioParam.ioResult) == noErr) {
  106.                 /* Do damned assembling */
  107.                 err = OnePassAsm(tempBuffer);
  108.                 InvalDump();
  109.                 InvalDisasm();
  110.                 }
  111.             DisposeHandle(tempBuffer);
  112.             }
  113.         else err = MemError();
  114.         }
  115.     (void)FSClose(asmFileRefN);
  116.     }
  117. InitCursor();
  118. return(err);
  119. }
  120.  
  121. /* OnePassAsm: assembles the file passed in the buffer */
  122.  
  123. static OSErr OnePassAsm(Handle fileBuffer)
  124. {
  125. Str255    tempS;
  126. Handle    SortedOpcodeTable;
  127. symtableHandle    SymbolTable;
  128. objtableHandle    ObjTable;
  129. Handle    tempH;
  130. Ptr    myEOF;
  131. long    ILC;
  132. ROpcodePtr    found;
  133. symtablePtr    foundsym;
  134. Size    ObjTabOffset, SymTabOffset, tmpSize;
  135. short    build;
  136. short    numinstr;
  137. OSErr    err;
  138. register Byte    i;
  139. register char *ex = nil;
  140. register char *copy;
  141.  
  142. err = noErr;
  143. ILC = (long)gILCBase << 1;
  144. DetachResource(SortedOpcodeTable = Get1Resource(krInstructions, kOPCODES));
  145. HNoPurge(SortedOpcodeTable);
  146. qsort((*SortedOpcodeTable) + 2, numinstr = (*(unsigned short *)*SortedOpcodeTable) + 1,
  147.     sizeof(ROpcode), compareMnem);
  148.  
  149. /* init symbol & object table */
  150. if ((SymbolTable = (symtableHandle)NewHandleGeneral(sizeof(symtable)*kGROW_SYMTAB))) {
  151.     if ((ObjTable = (objtableHandle)NewHandleGeneral(sizeof(objtable)*kGROW_OBJTAB))) {
  152.         SymTabOffset = 0L;
  153.         ObjTabOffset = 0L;
  154.         HLock(fileBuffer);
  155.         ex = *fileBuffer;
  156.         myEOF = (Ptr)((Size)ex + InlineGetHandleSize(fileBuffer));
  157.         do {
  158.             if (*ex == 13)
  159.                 ex++;
  160.             else {
  161.                 if (ispunct(*ex))
  162.                     while (*ex++ != 13)
  163.                         ;
  164.                 else {
  165.                     if (isspace(*ex) == 0) {
  166.                         copy = (char *)&tempS[1];
  167.                         i = 0;
  168.                         do {
  169.                             *copy++ = *ex++;
  170.                             i++;
  171.                             }
  172.                         while (isspace(*ex) == 0);
  173.                         tempS[0] = i;
  174.                         /* add to symbol table */
  175.                         if (SymTabOffset >= (tmpSize = InlineGetHandleSize((Handle)SymbolTable)))
  176.                             SetHandleSize((Handle)SymbolTable, tmpSize + sizeof(symtable)*kGROW_SYMTAB);
  177.                         tempH = (Handle)NewString(tempS);
  178.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->symb = (StringHandle)tempH;
  179.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->value = ILC;
  180.                         SymTabOffset += sizeof(symtable);
  181.                         }
  182.                     if (*ex == 13)
  183.                         ex++;
  184.                     else {
  185.                         while (isspace(*ex++))
  186.                             ;
  187.                         --ex;
  188.                         copy = (char *)&tempS;
  189.                         i = 0;
  190.                         do {
  191.                             *copy++ = *ex++;
  192.                             i++;
  193.                             }
  194.                         while (isspace(*ex) == 0);
  195.                         if (i > kOPCMAXLEN) {
  196.                             err = kasmErrInvalidOpcode;
  197.                             break;
  198.                             }
  199.                         else {
  200.                             while (i < kOPCMAXLEN) {
  201.                                 i++;
  202.                                 *copy++ = ' ';
  203.                                 }
  204.                             if (ObjTabOffset >= (tmpSize = InlineGetHandleSize((Handle)ObjTable)))
  205.                                 SetHandleSize((Handle)ObjTable, tmpSize + sizeof(objtable)*kGROW_OBJTAB);
  206.                             found = (ROpcodePtr)bsearch(&tempS, (*SortedOpcodeTable)+2,
  207.                                     numinstr, sizeof(ROpcode), compareMnem);
  208.                             if (found == nil) {
  209.                                 err = kasmErrInvalidOpcode;
  210.                                 break;
  211.                                 }
  212.                             else {
  213.                                 *(long *)&((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->length = *(long *)(&found->length);
  214.                                 i = found->class;
  215.                                 if (i == kCLASS_16_0) {
  216.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  217.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = 0L;
  218.                                     }
  219.                                 else {
  220.                                     while (isspace(*ex++))
  221.                                         ;
  222.                                     --ex;
  223.                                     if (*ex == '#') {
  224.                                         ++ex;
  225.                                         copy = (char *)&tempS[1];
  226.                                         i = 0;
  227.                                         do {
  228.                                             *copy++ = *ex++;
  229.                                             i++;
  230.                                             }
  231.                                         while (isspace(*ex) == 0);
  232.                                         tempS[0] = i;
  233.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  234.                                         StringToNum(tempS, &((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand);
  235.                                         }
  236.                                     else {
  237.                                         copy = (char *)&tempS[1];
  238.                                         i = 0;
  239.                                         do {
  240.                                             *copy++ = *ex++;
  241.                                             i++;
  242.                                             }
  243.                                         while (isspace(*ex) == 0);
  244.                                         tempS[0] = i;
  245.                                         tempH = (Handle)NewString(tempS);
  246.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = true;
  247.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = (long)tempH;
  248.                                         }
  249.                                     }
  250.                                 ObjTabOffset += sizeof(objtable);
  251.                                 }
  252.                             while (*ex++ != 13)
  253.                                 ;
  254.                             ILC += found->length;
  255.                             }
  256.                         }
  257.                     }
  258.                 }
  259.             }
  260.         while (ex < myEOF);
  261.         HUnlock(fileBuffer);
  262.         if (err == noErr)
  263.             /* check for ILC out of bounds */
  264.             if (ILC > kSIZE_RAM - 4096)
  265.                 err = kasmErrPotHeapDamage;
  266.         if (err == noErr) {
  267.             ILC = (long)gILCBase << 1;
  268.             qsort(*SymbolTable, SymTabOffset / sizeof(symtable), sizeof(symtable), cmpsymb);
  269.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable)) {
  270.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol) {
  271.                     foundsym = (symtablePtr)
  272.                         bsearch(&((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand,
  273.                         *SymbolTable, SymTabOffset / sizeof(symtable),
  274.                         sizeof(symtable), cmpsymb);
  275.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol = false;
  276.                     DisposeHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  277.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand =
  278.                             (foundsym ? (((objtablePtr)(*(Handle)ObjTable + tmpSize))->class >= kCLASS_16_16_REL
  279.                             ? (foundsym->value - ILC - ((objtablePtr)(*(Handle)ObjTable + tmpSize))->length) >> 1
  280.                             : foundsym->value) : (err = kasmErrSymbolNotDef, 0L));
  281.                     }
  282.                 switch (((objtablePtr)(*(Handle)ObjTable + tmpSize))->class) {
  283.                     case kCLASS_4_12:
  284.                     case kCLASS_4_12_REL:
  285.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  286.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_12));
  287.                         *(short *)(gMMemory + ILC) = build;
  288.                         ILC += 2;
  289.                         break;
  290.                     case kCLASS_5_11:
  291.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  292.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_11));
  293.                         *(short *)(gMMemory + ILC) = build;
  294.                         ILC += 2;
  295.                         break;
  296.                     case kCLASS_8_8:
  297.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  298.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_8));
  299.                         *(short *)(gMMemory + ILC) = build;
  300.                         ILC += 2;
  301.                         break;
  302.                     case kCLASS_16_0:
  303.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  304.                         ILC += 2;
  305.                         break;
  306.                     case kCLASS_16_16:
  307.                     case kCLASS_16_16_REL:
  308.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  309.                         ILC += 2;
  310.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand;
  311.                         ILC += 2;
  312.                         break;
  313.                     }
  314.                 }
  315.             }
  316.         if ((err != noErr) && (err != kasmErrSymbolNotDef))
  317.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable))
  318.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol)
  319.                     DisposeHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  320.         for(tmpSize = 0; tmpSize < SymTabOffset; tmpSize += sizeof(symtable))
  321.             DisposeHandle((Handle)((symtablePtr)(*(Handle)SymbolTable + tmpSize))->symb);
  322.         DisposeHandle((Handle)ObjTable);
  323.         }
  324.     else err = MemError();
  325.     DisposeHandle((Handle)SymbolTable);
  326.     }
  327. else err = MemError();
  328. DisposeHandle(SortedOpcodeTable);
  329. if (err > 0) {
  330.     InitCursor();
  331.     if (ex)
  332.         MyNumToString(1L + CountReturns(fileBuffer, ex), tempS);
  333.     else
  334.         *(short *)tempS = 0x013F;
  335.     ParamText(tempS, nil, nil, nil);
  336.     StopAlert_UPP(kALRT_ASM + err, myStdFilterProcNoCancel);
  337.     err = 0;
  338.     }
  339. return err;
  340. }
  341.  
  342. static long CountReturns(Handle fileBuffer, char *lastpos)
  343. {
  344. register char *scanptr;
  345. register char *end = StripAddress(lastpos);
  346. register long    cnt = 0L;
  347.  
  348. for ( scanptr = StripAddress(*fileBuffer); scanptr <= end; )
  349.     if (*scanptr++ == 13)
  350.         ++cnt;
  351. return cnt;
  352. }
  353.  
  354.  
  355. enum {
  356. kDLOG_ASMPREFS = 263,
  357. kItemAsmDestLoc = 3
  358. };
  359.  
  360. void DoAsmPrefsDialog(void)
  361. {
  362. Str255    AsmDestStr;
  363.  
  364. dialogItems    things[] = {{ ok, 0, 1L },
  365.                         { cancel, 0, 0L },
  366.                         { kItemAsmDestLoc, 0, 0L },
  367.                         { 0, 0, 0L}
  368.                         };
  369.  
  370. things[kItemAsmDestLoc-1].refCon = (long)&AsmDestStr;
  371.  
  372. ShortToHexString(gILCBase, AsmDestStr);
  373.  
  374. if (HandleMovableModalDialog(things, gPrefs.remembWind ? &gPrefs.asmPrefsTL : nil, nil, nil, nil, nil, nil,
  375.     AdjustMenus,
  376.     Handle_My_Menu,
  377.     DomyKeyEvent,
  378.     AsmPrefsPreProcessKey,
  379.     nil,
  380.     DoUpdate,
  381.     DoActivate,
  382.     DoHighLevelEvent,
  383.     DoOSEvent,
  384.     DoIdle,
  385.     ULONG_MAX,
  386.     kDLOG_ASMPREFS) == ok) {
  387.     HexStringToShort(AsmDestStr, (short *)&gILCBase);
  388.     }
  389. }
  390.  
  391. Boolean AsmPrefsPreProcessKey(EventRecord *thEv, DialogPtr theD)
  392. {
  393. //short    iHit;
  394. unsigned char    keypressed;
  395. Boolean    result = true;
  396.  
  397. keypressed = CHARFROMMESSAGE(thEv->message);
  398. if ((keypressed >= 'a') && (keypressed <= 'z')) {
  399.     keypressed -= 'a' - 'A';    /* cambiare! */
  400.     CHARFROMMESSAGE(thEv->message) = keypressed;
  401.     }
  402. //iHit = ((DialogPeek)theD)->editField + 1;
  403. if (keypressed >= 32 && ((thEv->modifiers & cmdKey) == 0)) {
  404.     result = ( Munger((Handle)GetString(kSTR_HEXALLOWED), 1L, &keypressed,
  405.                             1L, 0L, 0L) >= 0L );
  406.     }
  407. return result;
  408. }
  409.  
  410. /* AsmEditNumFilter: filterProc for the asm prefs dialog */
  411. /*
  412. static pascal Boolean AsmEditNumFilter(DialogPtr theD, EventRecord *thEv, short *iHit)
  413. {
  414. enum {
  415. kITEM_VALUE = 3
  416. };
  417.  
  418. GrafPtr    savePort;
  419. unsigned char    keypressed;
  420. register Boolean    retVal;
  421.  
  422. switch(thEv->what) {
  423.     case keyDown    :
  424.     case autoKey    :
  425.         keypressed = CHARFROMMESSAGE(thEv->message);
  426.         if ((keypressed >= 'a') && (keypressed <= 'z')) {
  427.             keypressed -= 'a' - 'A';
  428.             CHARFROMMESSAGE(thEv->message) = keypressed;
  429.             }
  430.         if ((keypressed >= 32) && (keypressed != 0x7F) && ((thEv->modifiers & cmdKey) == 0)) {
  431.             *iHit = kITEM_VALUE;
  432.             return( Munger((Handle)GetString(kSTR_HEXALLOWED), 1L, &keypressed, 1L, 0L, 0L) < 0L );
  433.             }
  434.         break;
  435.     case updateEvt:
  436.         if (theD != (DialogPtr)thEv->message) {
  437.             DoUpdate(thEv);
  438.             *iHit = kfakeUpdateItem;
  439.             return true;
  440.             }
  441.         break;
  442.     case activateEvt:
  443.         if (theD != (DialogPtr)thEv->message) {
  444.             DoActivate(thEv);
  445.             *iHit = kfakeUpdateItem;
  446.             return true;
  447.             }
  448.         break;
  449.     }
  450. GetPort(&savePort);
  451. SetPort(theD);
  452. retVal = StdFilterProc(theD, thEv, iHit);
  453. SetPort(savePort);
  454. return retVal;
  455. }
  456. */
  457.  
  458. /* compareMnem: used to compare opcodes in the opcode table */
  459.  
  460. static int compareMnem(const void *opc1, const void *opc2)
  461. {
  462.  
  463. return(*(long *)opc1 - *(long *)opc2);
  464. }
  465.  
  466. /* cmpsymb: used to compare strings in the Symbol Table */
  467.  
  468. static int cmpsymb(const void *opc1, const void *opc2)
  469. {
  470. return(RelString(**(StringHandle *)opc1, **(StringHandle *)opc2, true, true));
  471. }
  472.  
  473. #endif
  474.  
  475.